﻿using System;
using System.Collections.Generic;
using System.Text;

namespace ycdlib
{
	class CharBuffer
	{
		int ptr;
		List<char> buffer;

		public CharBuffer ()
		{
			ptr = 0;
			buffer = new List<char>();
		}

		public void Reset ()
		{
			ptr = 0;
		}


		/// <summary>
		/// バッファをリセットし、初期値として一文字入れる
		/// </summary>
		/// <param name="c">初期値に入れる一文字</param>
		public void Reset ( int c )
		{
			if( buffer.Count == 0 )
				buffer.Add( (char)c );
			else
				buffer[0] = (char)c;
			ptr = 1;
		}


		public void Add ( int c )
		{
			if( buffer.Count <= ptr )
				buffer.Add( (char)c );
			else
				buffer[ptr] = (char)c;
			++ptr;
		}

		public char this[ int index ]
		{
			get { return buffer[index]; }
			set { buffer[index] = value; }
		}

		public int Length { get { return ptr; } }

		public bool HasContents { get { return ptr > 0; } }


		public override string ToString ()
		{
			if( ptr==0 ) return string.Empty;
			char[] b = new char[ptr];
			buffer.CopyTo( 0, b, 0, ptr );

			return new string( b );
		}


		internal enum NumberStatus
		{
			FAILURE = 0,
			SIGN,
			INTEGER,
			COMMA,
			DOT,
			DECIMAL,	//	小数
			EX,			//	e
			EXSIGN,		//	+/-
			EXNUM,
		}

		public uint Test ()
		{
			bool isNumAlpha = true;
			bool isAlpha = true;
			bool isASCII = true;
			bool isNumFirst = false;

			NumberStatus ns = NumberStatus.FAILURE;

			char c;
			int I = ptr;
			if( I==0 ) return 0;

			c = buffer[0];
			if( c=='-' )
			{
				ns = NumberStatus.SIGN;
			}else if( c>='0' && c<='9' )
			{
				ns = NumberStatus.INTEGER;
				isNumFirst = true;
			}else if( c=='.' )
			{
				ns = NumberStatus.DOT;
			}else
			{
				if( (c>='A' && c<='Z') || c=='_' || (c>='a' && c<='z') )
				{
				}else
				{
					isAlpha = false;
					if( c>=0x80 )
						isASCII = false;
				}
			}

			for( int i=1 ; i<I ; ++i )
			{
				c = buffer[i];
				if( ns != NumberStatus.FAILURE )
				{
					if( c=='.' )
					{
						if( ns==NumberStatus.SIGN )
						{
							ns = NumberStatus.FAILURE;
						}
						if( ns==NumberStatus.INTEGER )
							ns = NumberStatus.DOT;
						else
							ns = NumberStatus.FAILURE;
					}else if( c==',' )
					{
						if( ns==NumberStatus.INTEGER )
							ns = NumberStatus.COMMA;
						else
							ns = NumberStatus.FAILURE;
					}else if( c=='e' )
					{
						if( ns==NumberStatus.DECIMAL )
							ns = NumberStatus.EX;
						else
							ns = NumberStatus.FAILURE;
					}else if( c=='-' || c=='+' )
					{
						if( ns==NumberStatus.EX )
							ns = NumberStatus.EXSIGN;
					}else if( c>='0' && c<='9' )
					{
						if( ns==NumberStatus.SIGN || ns==NumberStatus.COMMA )
							ns = NumberStatus.INTEGER;
						else if( ns==NumberStatus.DOT )
							ns = NumberStatus.DECIMAL;
						else if( ns==NumberStatus.EX || ns==NumberStatus.EXSIGN )
							ns = NumberStatus.EXNUM;
					}else
					{
						ns = NumberStatus.FAILURE;
					}
				}
				if( (c<'A' || c>'Z') && c!='_' && (c<'a' || c>'z') )
				{
					isAlpha = false;
					if( c<'0'||c>'9' )
					{
						isNumAlpha = false;
						if( c>=0x80 )
							isASCII = false;
					}
				}
			}

			uint __result = (uint)ns;
			if( isAlpha )		__result |= 0x0100;
			if( isNumAlpha )	__result |= 0x0200;
			if( isASCII )		__result |= 0x0400;
			if( isNumFirst )	__result |= 0x0800;

			return __result;
		}
	}
}
